Refactor: 문서 목록 CQRS Read Model 전환 및 Domain Event Outbox 추가#204
Conversation
…스케이스 메서드화로 호출부에서의 의미 들어나게 변경 - flyway 마이그레이션 sql문 생성(originType 삭제)
- Factory -> JobEnqueuer - DeleteService -> DeleteExecutor - MongoDeleteOutboxCreateService를 제거하고 JobEnqueuer에서 saveAndFlush를 직접 호출 - 변경된 이름과 중복 충돌 처리 방식에 맞춰 테스트 수정
- 도메인 이벤트 저장용 outbox 엔티티와 마이그레이션을 추가 - outbox relay, lifecycle service, wake-up listener를 추가 - 로컬 dispatcher를 통해 문서 목록 projector로 이벤트를 전달하도록 구성 - 문서 목록 조회용 Mongo read model과 payload를 추가 - 신규 JPA/Mongo repository 패키지를 스캔 설정에 등록
- 문서 목록 projection payload를 이벤트 타입별 record로 분리 - DocListProjector가 이벤트 타입별 payload를 역직렬화하도록 변경 - DocListReadModel에 생성/제목/활동/썸네일/삭제 이벤트별 반영 메서드를 추가 - DocPayloadFactory를 추가해 이벤트 payload 생성 책임을 분리
- 문서 생성 트랜잭션에서 DOC_CREATED outbox 이벤트를 저장하도록 연결 - 문서 제목 변경 시 DOC_TITLE_CHANGED outbox 이벤트를 저장하도록 연결 - 제목 변경 단위 테스트에 outbox publish 검증을 추가
- @EnableAsync 설정을 AsyncConfig로 분리 - outbox wake-up listener가 전용 executor를 사용하도록 변경 - 트랜잭션 커밋 이후 이벤트만 처리하도록 fallbackExecution을 제거
- 브랜치 생성, 병합, 커밋 생성, 저장 수정, 썸네일 확정, 문서 삭제 흐름에서 문서 목록 read model 갱신용 domain event outbox를 발행 연결 - 브랜치가 save를 가진다는 현재 도메인 규칙에 맞춰 커밋 통합 테스트 fixture를 보정
- DocListProjector의 이벤트별 read model 반영과 eventId 기반 idempotency를 단위 테스트로 검증 - 오래된 DOC_DELETED 이벤트가 최신 read model 상태를 덮어쓰지 않도록 lastProjectedEventId 반영을 보정 - DomainEventOutboxRelay의 DONE/retry/FAILED 상태 전이를 통합 테스트로 검증 - relay, dispatcher, projector, Mongo read model까지 이어지는 DOC_CREATED projection 통합 테스트를 추가
- DocService를 DocCommandService로 분리하고 문서 목록/검색/그래프 조회를 DocQueryService로 이동 - 문서 목록/검색 응답을 DocListReadModel 기반으로 매핑하도록 변경 - 기존 SQL 목록 조립용 DocListAssembler를 제거하고 read model mapper를 추가 - command/query 분리에 맞춰 컨트롤러 및 테스트를 정리
- 컨트롤러 테스트의 MockMvc print 출력을 제거해 테스트 로그 노이즈를 줄임 - test/local/stg/prod 환경의 SQL 및 bind parameter 로그 레벨을 명시 - local 환경에서는 필요 시 환경변수로 SQL 로그를 켤 수 있도록 조정
- 문서 도메인 테스트를 api/app 단위와 통합 테스트 패키지로 정리 - DocQueryService 목록 응답에서 thumbnailObjectKey null/blank 처리 검증 추가 - thumbnailObjectKey가 있으면 CDN URL로 변환되는지 검증
- local 프로필에서 Mongo DB를 시작/종료 시 정리하는 cleanup 컴포넌트 추가 - test 프로필에서 테스트 DB 정리를 위한 cleanup 컴포넌트 추가 - 안전한 DB 이름(-local, -test)에 대해서만 drop 하도록 보호 로직 추가 - cleanup 동작을 검증하는 단위 테스트 추가
- 커밋 조회/검증 책임을 CommitReader로 분리 - 커밋 저장/삭제 책임을 CommitWriter로 분리 - CQRS QueryService와 혼동되는 기존 CommitQueryService 명명을 제거
- 브랜치 조회/검증 책임을 BranchReader로 분리 - 브랜치 생성/저장/삭제 책임을 BranchWriter로 분리 - CQRS QueryService와 혼동되는 기존 BranchQueryService 명명을 제거
- 저장 조회/검증 책임을 SaveReader로 분리 - 저장 생성/갱신 책임을 SaveWriter로 분리 - CQRS QueryService와 혼동되는 기존 SaveQueryService 명명을 제거
- 이미지 조회 전용 서비스를 ImageReader로 변경 - 썸네일 영속성 접근을 ThumbnailStore로 정리 - CQRS QueryService와 혼동되는 기존 QueryService 명명을 제거
- 기존 Doc 데이터를 batch 단위로 조회해 DocListReadModel을 초기 생성 - Mongo setOnInsert upsert로 기존 read model을 덮어쓰지 않도록 처리 - backfill profile에서 실행되는 one-off job과 테스트 설정 추가
- local backfill 실행 스크립트를 추가 - backfill profile에서 local initializer와 cleanup이 실행되지 않도록 조정 - backfill 실행 시 domain event relay bean 의존성은 유지하되 scheduler 실행은 지연
- 목록 조회에서 deleted=true read model이 제외되는지 검증 - 제목 검색 조회에서도 삭제된 read model이 제외되는지 검증
Refactor: 문서 목록 CQRS Read Model 전환 및 Domain Event Outbox 추가
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 306bcf99ed
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| domainEventOutboxPublisher.publish(DomainEventType.DOC_THUMBNAIL_CHANGED, AggregateType.DOC, docId, | ||
| DocPayloadFactory.thumbnailChanged(docId, image.getObjectKey(), ThumbnailStatus.READY)); |
There was a problem hiding this comment.
Project the pending thumbnail status
For a document receiving its first thumbnail, requestUpdate() changes the MySQL thumbnail status from EMPTY to PENDING, but the read model only receives an event after finalization with READY. Since document-list responses now come exclusively from this read model, list and search APIs continue reporting EMPTY throughout thumbnail generation instead of the PENDING status that the previous SQL-backed list exposed. Publish the status transition when the update is requested.
Useful? React with 👍 / 👎.
🛰️ Issue Number
🪐 작업 내용
문서목록 cqrs 전환
📚 Reference
✅ Check List